"""
配置管理器模块

负责加载、验证和提供应用程序配置
支持从JSON文件、环境变量和命令行参数加载配置
"""

import json
import os
import argparse
from typing import Dict, Any, Optional

class ConfigManager:
    """配置管理器类，处理应用程序的所有配置"""
    
    def __init__(self, config_file: str = "config/default.json"):
        """
        初始化配置管理器
        
        Args:
            config_file: 配置文件路径
        """
        self.config_file = config_file
        self.config = {}
        self.args = None
        
    def load_config(self) -> Dict[str, Any]:
        """
        加载配置，顺序为：默认配置 -> 配置文件 -> 环境变量 -> 命令行参数
        后加载的配置会覆盖先加载的配置
        
        Returns:
            合并后的配置
        """
        # 加载默认配置
        self.config = self._get_default_config()
        
        # 从配置文件加载
        file_config = self._load_from_file()
        if file_config:
            self._update_nested_dict(self.config, file_config)
        
        # 从环境变量加载
        env_config = self._load_from_env()
        if env_config:
            self._update_nested_dict(self.config, env_config)
        
        # 从命令行参数加载
        self._parse_args()
        
        return self.config
    
    def _get_default_config(self) -> Dict[str, Any]:
        """获取默认配置"""
        return {
            "app": {
                "log_level": "info",
                "debug": False
            },
            "audio": {
                "temp_dir": "temp",
                "chunk_size": 1024,
                "format": "int16",
                "channels": 1,
                "rate": 16000,
                "record_seconds": 5
            },
            "stt": {
                "type": "whisper",
                "model": "base",
                "language": "zh"
            },
            "tts": {
                "type": "edge_tts",
                "voice": "zh-CN-XiaoxiaoNeural",
                "rate": "+0%",
                "volume": "+0%"
            },
            "ai": {
                "type": "ollama",
                "model_name": "llama3:8b",
                "temperature": 0.7,
                "endpoint": "http://localhost:11434/api/generate",
                "max_tokens": 2000
            }
        }
    
    def _load_from_file(self) -> Optional[Dict[str, Any]]:
        """从文件加载配置"""
        try:
            if os.path.exists(self.config_file):
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
        except Exception as e:
            print(f"警告：加载配置文件失败 - {e}")
        return None
    
    def _load_from_env(self) -> Dict[str, Any]:
        """从环境变量加载配置"""
        env_config = {}
        
        # 新的环境变量映射
        env_mappings = {
            "AI_TYPE": ["ai", "type"],
            "AI_MODEL_NAME": ["ai", "model_name"],
            "AI_ENDPOINT": ["ai", "endpoint"],
            "AI_TEMPERATURE": ["ai", "temperature"],
            "STT_TYPE": ["stt", "type"],
            "STT_MODEL": ["stt", "model"],
            "STT_LANGUAGE": ["stt", "language"],
            "TTS_TYPE": ["tts", "type"],
            "TTS_VOICE": ["tts", "voice"],
            "AUDIO_RECORD_SECONDS": ["audio", "record_seconds"],
            "DEBUG": ["app", "debug"],
            "LOG_LEVEL": ["app", "log_level"]
        }
        
        for env_var, config_path in env_mappings.items():
            value = os.environ.get(env_var)
            if value is not None:
                # 处理布尔值和数字
                if value.lower() in ["true", "false"]:
                    value = value.lower() == "true"
                elif value.isdigit():
                    value = int(value)
                elif value.replace(".", "", 1).isdigit():
                    value = float(value)
                
                # 构建嵌套字典
                current = env_config
                for key in config_path[:-1]:
                    if key not in current:
                        current[key] = {}
                    current = current[key]
                current[config_path[-1]] = value
                
        return env_config
    
    def _parse_args(self):
        """解析命令行参数并更新配置"""
        parser = argparse.ArgumentParser(description='AI对话系统')
        
        # 基本参数
        parser.add_argument('--debug', action='store_true', help='启用调试模式')
        parser.add_argument('--file', type=str, help='指定要处理的音频文件路径')
        parser.add_argument('--config', type=str, help='指定配置文件路径')
        
        # 语音识别模型参数
        parser.add_argument('--stt-type', type=str, choices=['whisper', 'mock'], 
                            help='语音识别类型')
        parser.add_argument('--stt-model', type=str,
                            choices=['tiny', 'base', 'small', 'medium', 'large'],
                            help='Whisper模型大小')
        
        # AI模型参数
        parser.add_argument('--ai-type', type=str, choices=['ollama', 'openai', 'mock'],
                            help='AI类型')
        parser.add_argument('--ai-model', type=str,
                            help='AI模型名称')
        parser.add_argument('--api-endpoint', type=str,
                            help='API端点地址')
        
        # 录音参数
        parser.add_argument('--record-time', type=int,
                            help='录音时长(秒)')
        
        # TTS参数
        parser.add_argument('--tts-type', type=str, choices=['edge_tts', 'mock'],
                            help='文本转语音类型')
        parser.add_argument('--tts-voice', type=str,
                            help='TTS语音')
        
        self.args = parser.parse_args()
        
        # 更新配置文件路径
        if self.args.config:
            self.config_file = self.args.config
            file_config = self._load_from_file()
            if file_config:
                self._update_nested_dict(self.config, file_config)
        
        # 更新配置
        if self.args.debug:
            self.config["app"]["debug"] = True
        
        if self.args.stt_type:
            self.config["stt"]["type"] = self.args.stt_type
            
        if self.args.stt_model:
            self.config["stt"]["model"] = self.args.stt_model
            
        if self.args.ai_type:
            self.config["ai"]["type"] = self.args.ai_type
            
        if self.args.ai_model:
            self.config["ai"]["model_name"] = self.args.ai_model
            
        if self.args.api_endpoint:
            self.config["ai"]["endpoint"] = self.args.api_endpoint
            
        if self.args.record_time:
            self.config["audio"]["record_seconds"] = self.args.record_time
            
        if self.args.tts_type:
            self.config["tts"]["type"] = self.args.tts_type
            
        if self.args.tts_voice:
            self.config["tts"]["voice"] = self.args.tts_voice
    
    def _update_nested_dict(self, d: Dict[str, Any], u: Dict[str, Any]) -> Dict[str, Any]:
        """递归更新嵌套字典"""
        for k, v in u.items():
            if isinstance(v, dict) and k in d and isinstance(d[k], dict):
                self._update_nested_dict(d[k], v)
            else:
                d[k] = v
        return d
    
    def get_audio_config(self) -> Dict[str, Any]:
        """获取音频配置"""
        return self.config.get("audio", {})
    
    def get_stt_config(self) -> Dict[str, Any]:
        """获取语音转文本配置"""
        return self.config.get("stt", {})
    
    def get_tts_config(self) -> Dict[str, Any]:
        """获取文本转语音配置"""
        return self.config.get("tts", {})
    
    def get_ai_config(self) -> Dict[str, Any]:
        """获取AI模型配置"""
        return self.config.get("ai", {})
    
    def get_app_config(self) -> Dict[str, Any]:
        """获取应用配置"""
        return self.config.get("app", {})
    
    def is_debug(self) -> bool:
        """是否为调试模式"""
        return self.config.get("app", {}).get("debug", False)
    
    def get_input_file(self) -> Optional[str]:
        """获取输入文件路径"""
        return self.args.file if self.args and self.args.file else None 